package com.gitee.zhuyunlong2018.mybatisplusrelations.binder;

import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.gitee.zhuyunlong2018.mybatisplusrelations.cache.RelationCache;
import com.gitee.zhuyunlong2018.mybatisplusrelations.context.ListContext;
import com.gitee.zhuyunlong2018.mybatisplusrelations.exceptions.RelationAnnotationException;
import com.gitee.zhuyunlong2018.mybatisplusrelations.handler.*;
import com.gitee.zhuyunlong2018.mybatisplusrelations.func.IGetter;
import com.gitee.zhuyunlong2018.mybatisplusrelations.utils.BeanUtils;

import java.util.List;

/**
 * 主表selectList的绑定器
 *
 * @param <T>
 */
public class ListBinder<T> extends Binder<T> {

    public ListBinder(List<T> list) {
        context = new ListContext<>(this, list);
    }

    /**
     * 多对多
     *
     * @param propertyGetter
     * @param <R>
     * @return
     */
    @Override
    public <R extends Model<?>> IManyBindHandler<T, R> manyBindMany(IGetter<T, List<R>> propertyGetter) {
        if (context.useless(propertyGetter)) {
            return (IManyBindHandler<T, R>) useLessBinder();
        }
        if (null == context.getCache(propertyGetter).getLinkEntityClass()) {
            throw new RelationAnnotationException("没有中间表无法绑定多对多");
        }
        ListManyBindManyHandler<T, R> handler = new ListManyBindManyHandler<>(context, propertyGetter);
        handlers.add(handler);
        return handler;
    }

    /**
     * 列表 绑定一对多
     *
     * @param propertyGetter
     * @param <R>
     * @return
     */
    @Override
    public <R extends Model<?>> IHandler<T, R> bindMany(IGetter<T, List<R>> propertyGetter) {
        if (context.useless(propertyGetter)) {
            return useLessBinder();
        }
        ListBindManyHandler<T, R> handler = new ListBindManyHandler<>(context, propertyGetter);
        handlers.add(handler);
        return handler;
    }

    /**
     * 列表 绑定一对一
     *
     * @param propertyGetter
     * @param <R>
     * @return
     */
    @Override
    public <R extends Model<?>> IHandler<T, R> bindOne(IGetter<T, R> propertyGetter) {
        if (context.useless(propertyGetter)) {
            return useLessBinder();
        }
        ListBindOneHandler<T, R> handler = new ListBindOneHandler<>(context, propertyGetter);
        handlers.add(handler);
        return handler;
    }

}
